import os
import subprocess
import time

from AutoWool.main.utils.log_utils import Log
from AutoWool.main.utils.system_utils import SystemUtils


class TaskUtils:

    # 轮询执行延迟任务，满足条件则退出(阻塞的)
    @staticmethod
    def execute_delay_task(break_judge_func, max_delay_time_second, task_name='', **args) -> int:
        anchor_time = int(time.time())
        Log.log('execute_delay_task anchor_time=' + str(anchor_time))
        while True:
            if break_judge_func(**args):
                Log.log(task_name + '执行成功')
                return 0
            else:
                Log.log('不满足' + task_name + ' 条件，继续执行延时检测任务')
                SystemUtils.delayTime(1)
                cur_time = int(time.time())
                Log.log('cur_time=' + str(cur_time) + ' anchor_time' + str(
                    anchor_time) + ' max_delay_time_second=' + str(max_delay_time_second))
                if cur_time >= anchor_time + max_delay_time_second:  # time 单位是秒,不能 *1000
                    # Log.error(taskName + '超时!')
                    return -1

    # 该方法用来执行命令行命令，并实时打印输出，没有返回值
    @staticmethod
    def execute_cmd_task_real_time(cmd):
        # 使用 subprocess 防止 os.popen() 异步 io
        if hasattr(os, 'setsid'):  # Windows 不支持 os.setsid 操作
            downloadProces = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE,
                                              preexec_fn=os.setsid)  # shell = True 也不现实命令行黑色窗口？
        else:
            downloadProces = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE,
                                              stderr=subprocess.STDOUT)
            # downloadProces = subprocess.Popen(downLoadcmd, shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
        # 创建超时任务，但是貌似不好使？(要在 process.communicate() 之前)，如果超时则杀死下载子进程
        try:
            Log.log("开始使用 subprocess.Popen 执行任务 " + str(cmd))
            count = 0
            while True:
                line = downloadProces.stdout.readline()
                if not line:
                    break
                # Log.log(line)
                count += 1
                if count % 10 == 0:
                    Log.log('正在执行任务...')
            stdout, stderr = downloadProces.communicate()
            exit_code = downloadProces.returncode
            Log.log("任务执行完成，exit_code = " + str(exit_code) + " stdout=" + str(stdout) + " stderr=" + str(stderr))
        finally:
            SystemUtils.killProcess(downloadProces)
